﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using Controllers;
using Interfaces;
using System.Windows.Controls;

namespace Hesehus
{
    public partial class Frontend
    {
        #region Fields

        private readonly StartUp _window;
        readonly Controller _controller;
        private readonly string[] _materials = new[] { "Vælg materiale", "Silke", "Bomuld", "Uld", "Læder", "Polyester", "Nylon" };
        private readonly string[] _maxPrices = new[] { "Vælg max Pris", "100", "200", "300", "400", "500", "600", "700", "800", "900", "1000", "1200", "1500", "1800", "2000" };
        private readonly string[] _orderBy = new[] { "Sorter efter", "Max pris", "Navn" };

        private const int ItemsPerPage = 9;
        private int _rowCount;
        private IEnumerable<ISearchData> _searchData;

        #region Søgekriterier

        //Felter til at holde data fra combobox som bruges til søgningen
        private int _brandId, _categoryId, _colorId, _sizeId;
        private decimal _maxPris;
        private string _search;
        private string _material;
        private string _order;
        private int _hasImage;

        #endregion

        #endregion

        #region Creation

        public Frontend(StartUp window)
        {
            InitializeComponent();
            _window = window;
            _controller = new Controller();
            var defaultComboboxItem = new DefaultComboboxItem();

            //Sætter display data til default tab.
            tabDisplayData.Focus();

            //Tilføjer materialer til cmbMaterial
            cmbMaterial.ItemsSource = _materials;

            //Tilføjer max priser til cmbMaxPrice
            cmbMaxPrice.ItemsSource = _maxPrices;

            //Tilføjer sorterings kriterier til cmbSortBy
            cmbOrderBy.ItemsSource = _orderBy;

            //Tilføjer brands til cmbBrands
            defaultComboboxItem.Name = "Vælg brand";
            cmbBrand.Items.Add(defaultComboboxItem);
            _controller.GetBrands().ForEach(e => cmbBrand.Items.Add(e));

            //Tilføjer kategori til cmbCategory
            defaultComboboxItem.Name = "Vælg kategori";
            cmbCategory.Items.Add(defaultComboboxItem);
            _controller.GetCategories().ForEach(e => cmbCategory.Items.Add(e));

            //Tilføjer farver til cmbColor
            defaultComboboxItem.Name = "Vælg farve";
            cmbColor.Items.Add(defaultComboboxItem);
            _controller.GetAllColors().ForEach(e => cmbColor.Items.Add(e));

            //Tilføjer størrelser til cmbSize
            defaultComboboxItem.Name = "Vælg størrelse";
            cmbSize.Items.Add(defaultComboboxItem);
            _controller.GetAllSizes().ForEach(e => cmbSize.Items.Add(e));

            //Disabling btnReset
            btnReset.IsEnabled = false;
        }

        #endregion

        #region Private Methods

        //LoadListBoxData tager vores collection med søgeresultater og tilføjer det til GUI
        private void LoadListBoxData()
        {
            lbGallery.ItemsSource = null;
            lbGallery.ItemsSource = _searchData;
        }

        //Tager de valgte comboboxes og søgefelter og gemmer det i globale fields
        public void SetSearchCriterias()
        {
            _search = (txtSearch.Text == "Søg her" || txtSearch.Text == "") ? "" : txtSearch.Text;

            _order = (string)cmbOrderBy.SelectedItem;

            Decimal.TryParse((string)cmbMaxPrice.SelectedItem, out _maxPris);

            _maxPris = 0;

            if (cmbMaxPrice.SelectedIndex != 0) Decimal.TryParse((string) cmbMaxPrice.SelectedItem, out _maxPris);
            _order = (cmbOrderBy.SelectedIndex != 0) ? (string) cmbOrderBy.SelectedItem : "";
            _material = (cmbMaterial.SelectedIndex != 0) ? (string) cmbMaterial.SelectedItem : "";
            _brandId = (cmbBrand.SelectedIndex != 0) ? ((IBrand) cmbBrand.SelectedItem).Id : 0;
            _categoryId = (cmbCategory.SelectedIndex != 0) ? ((ICategory) cmbCategory.SelectedItem).Id : 0;
            _colorId = (cmbColor.SelectedIndex != 0) ? ((IColor) cmbColor.SelectedItem).Id : 0;
            _sizeId = (cmbSize.SelectedIndex != 0) ? ((ISizeModel) cmbSize.SelectedItem).Id : 0;

            _hasImage = (cbPicture.IsChecked == null || cbPicture.IsChecked == false) ? 0 : 1;
        }

        //Basert på offset og limit henter den data ud fra databasen afhængig af de valgte søgekriterier
        private IEnumerable<ISearchData> Search(int offset, int limit)
        {
            try
            {
                IEnumerable<ISearchData> result = _controller.SearchGenericItems(offset, limit, _colorId, _brandId, _categoryId, _sizeId, _search, _material, _maxPris,
                                              _hasImage, _order);
                return result;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
                return null;
            }
        }

        //Laver paging knapper / links
        private void CreatePaginationLinks(int currentPage)
        {
            spPagination.Children.Clear();
            double pages = Math.Ceiling((double)(_rowCount / ItemsPerPage) + 1);

            if (_rowCount%ItemsPerPage == 0) pages--;

            //hvis nuværende side er 4 eller større skal der vises en tilbage knap
            if (currentPage - 1 >= 3)
            {
                var button = new Button();
                button.SetResourceReference(FrameworkElement.StyleProperty, "myStyle");
                button.Tag = (currentPage - 1);
                button.Content = "◄";
                button.Click += PagingButton_Click;
                spPagination.Children.Add(button);
            }

            for (int i = 1; i <= pages; i++)
            {
                if (pages != 1)
                {
                    //Disable nuværende side
                    if (currentPage == i)
                    {
                        var button = new Button();
                        button.SetResourceReference(FrameworkElement.StyleProperty, "myStyle");
                        button.Tag = i;
                        button.Content = i.ToString();
                        button.IsEnabled = false;
                        button.Click += PagingButton_Click;
                        spPagination.Children.Add(button);
                    }
                    else
                    {
                        int minPage = 3;
                        int maxPage = 3;

                        if (currentPage == 1) minPage = 6;
                        if (currentPage == 2) minPage = 5;
                        if (currentPage == 3) minPage = 4;

                        if (currentPage == pages) maxPage = 6;
                        if (currentPage == pages - 1) maxPage = 5;
                        if (currentPage == pages - 2) maxPage = 4;

                        if (i < currentPage + minPage && i > currentPage - maxPage)
                        {
                            var button = new Button();
                            button.SetResourceReference(FrameworkElement.StyleProperty, "myStyle");
                            button.Tag = i;
                            button.Content = (i).ToString();
                            button.Click += PagingButton_Click;
                            spPagination.Children.Add(button);
                        }
                    }
                }
            }
            //Hvis nuværende side er 4 eller flere fra sidste side skal der vises en frem knap
            if (currentPage + 3 <= pages)
            {
                var button = new Button();                
                button.SetResourceReference(FrameworkElement.StyleProperty, "myStyle");
                button.Tag = (currentPage + 1);
                button.Content = "►";
                button.Click += PagingButton_Click;
                spPagination.Children.Add(button);
            }

        }
        //finder ud af antallet af total resulatater samt henter søgeresulatater ud
        private void DoSearch()
        {
            try
            {
                SetSearchCriterias();


                int rowCount = _controller.GetRowCount(_colorId, _brandId, _categoryId, _sizeId, _search, _material, _maxPris,
                                              _hasImage, _order);

                _rowCount = rowCount;
                CreatePaginationLinks(1);

                _searchData = Search(1, ItemsPerPage);

                if (!_searchData.Any()) MessageBox.Show("Der blev ikke fundet nogen resultater!");
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }

        #endregion

        #region Events

        //Henter resultatet ud alt efter hvilket link/knap man clicker på samt laver nye links/knapper
        void PagingButton_Click(object sender, RoutedEventArgs e)
        {
            var button = (Button)sender;

            int page = (int)button.Tag;
            int offset = ((page - 1) * ItemsPerPage);

            _searchData = Search(offset + 1, ItemsPerPage);
            LoadListBoxData();
            CreatePaginationLinks(page);
        }

        private void tabGoBack_MouseUp(object sender, MouseButtonEventArgs e)
        {
            _window.Content = new Navigation(_window);
        }

        private void txtSearch_GotFocus(object sender, RoutedEventArgs e)
        {
            if (txtSearch.Text == "Søg her")
                txtSearch.Text = "";
        }

        private void txtSearch_LostFocus(object sender, RoutedEventArgs e)
        {
            if (txtSearch.Text == "")
                txtSearch.Text = "Søg her";
        }

        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            DoSearch();
            LoadListBoxData();
            
            btnReset.IsEnabled = true;
        }

        #region StateManagement

        //Resetter alle de valgte værdier
        private void btnReset_Click(object sender, RoutedEventArgs e)
        {
            txtSearch.Text = "Søg her";
            cmbBrand.SelectedIndex = 0;
            cmbCategory.SelectedIndex = 0;
            cmbMaterial.SelectedIndex = 0;
            cmbColor.SelectedIndex = 0;
            cmbSize.SelectedIndex = 0;
            cmbMaxPrice.SelectedIndex = 0;
            cmbSize.SelectedIndex = 0;
            cmbOrderBy.SelectedIndex = 0;
            cbPicture.IsChecked = false;
            lbGallery.ItemsSource = null;
            spPagination.Children.Clear();
            btnReset.IsEnabled = false;
        }

        private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (txtSearch.Text != "Søg her")
                btnReset.IsEnabled = true;
        }

        private void cmbBrand_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbCategory_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbMaterial_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbMaxPrice_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cmbOrderBy_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        private void cbPicture_Checked(object sender, RoutedEventArgs e)
        {
            btnReset.IsEnabled = cmbBrand.SelectedIndex != 0;
            btnReset.IsEnabled = cmbCategory.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaterial.SelectedIndex != 0;
            btnReset.IsEnabled = cmbColor.SelectedIndex != 0;
            btnReset.IsEnabled = cmbSize.SelectedIndex != 0;
            btnReset.IsEnabled = cmbMaxPrice.SelectedIndex != 0;
            btnReset.IsEnabled = cmbOrderBy.SelectedIndex != 0;
            btnReset.IsEnabled = true;
        }

        #endregion

        #endregion

        #region Custom window handlers

        private void Close(object sender, MouseButtonEventArgs e)
        {
            _window.Close();
        }

        private void DragMove(object sender, MouseButtonEventArgs e)
        {
            _window.DragMove();
        }

        private void Minimize(object sender, MouseButtonEventArgs e)
        {
            _window.WindowState = WindowState.Minimized;
        }

        private void Normal(object sender, MouseButtonEventArgs e)
        {
            if (_window.windowState)
            {
                _window.WindowState = WindowState.Maximized;
                _window.windowState = false;
            }
            else
            {
                _window.WindowState = WindowState.Normal;
                _window.windowState = true;
            }
        }

        #endregion

    }

}
